package com.sjzd.meeting.controller;

import com.alibaba.fastjson.JSONObject;
import com.sjzd.meeting.pojo.User;
import com.sjzd.meeting.pojo.WxUser;
import com.sjzd.meeting.service.IUserService;
import com.sjzd.meeting.service.IWxUserService;
import com.sjzd.weixin.utils.WxUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 *  微信网页授权控制器
 */
@Controller
@RequestMapping("/weixin")
public class WxOauthController {

    private static final Logger log = LoggerFactory.getLogger(WxOauthController.class);

    @Value("${wx.appID}")
    private String appID;

    @Value("${wx.appsecret}")
    private String secret;

    @Value("${wx.domainName}")
    private String domainName;

    @Autowired
    private IUserService userService;

    @Autowired
    private IWxUserService wxUserService;


    /**
     * 显示获权
     *
     * @param resp
     * @throws IOException
     */
    @RequestMapping("/oauth")
    public void oauth(HttpServletResponse resp) throws IOException {
        String redirect_uri = "";
        try {
            redirect_uri = URLEncoder.encode(domainName + "/weixin/callback", "UTF-8");
        } catch (UnsupportedEncodingException e) {
            log.error("微信网页授权的回调路径encode编码错误！e : {}", e.getCause());
        }
        String url  = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
                "appid=" + appID +
                "&redirect_uri="+redirect_uri+"&response_type=code&scope=snsapi_base&state=sjzd#wechat_redirect";
        resp.sendRedirect(url);
        return;
    }

    @RequestMapping("/callback")
    public ModelAndView callback(HttpServletRequest req, ModelAndView modelAndView) {
        // 获取code
        String code = req.getParameter("code");
        // 认证服务器，通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token不同
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
                "appid=" + appID +
                "&secret=" + secret +
                "&code="+ code +"&grant_type=authorization_code";
        String json = WxUtils.httpRequest(url, "GET", null);
        JSONObject jsonObject = JSONObject.parseObject(json);
        if (null != jsonObject.getInteger("errcode")) {
            log.error("网页授权失败，errcode : {}, errmsg : {}",
                    jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
            modelAndView.setViewName("error");
            return modelAndView;
        }
        String access_token = jsonObject.getString("access_token");
        String openid = jsonObject.getString("openid");

        // 访问服务器资源
        url = " https://api.weixin.qq.com/sns/userinfo?" +
                "access_token=" + access_token + "&openid=" + openid + "&lang=zh_CN";
        json = WxUtils.httpRequest(url, "GET", null);
        jsonObject = JSONObject.parseObject(json);

        // 跳转到用户信息页面
        modelAndView.addObject("jsonObject", jsonObject);
        modelAndView.setViewName("weixin/wxUserInfo");
        return modelAndView;
    }

    /**
     * 点击个人中心后的一些处理，通过回调拿到用户的openid
     *
     * @param resp
     * @throws IOException
     */
    @RequestMapping("/selfCenter")
    public void selfCenter(HttpServletResponse resp) throws IOException {
        String redirect_uri = "";
        try {
            redirect_uri = URLEncoder.encode(domainName + "/weixin/selfCenterCallback", "UTF-8");
        } catch (UnsupportedEncodingException e) {
            log.error("微信网页授权的回调路径encode编码错误！e : {}", e.getCause());
        }
        String url  = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
                "appid=" + appID +
                "&redirect_uri="+redirect_uri+"&response_type=code&scope=snsapi_base&state=sjzd#wechat_redirect";
        resp.sendRedirect(url);
        return;
    }

    /**
     * 点击 个人中心 回调处理：
     * 1.通过静默授权方式获取用户的openid
     * 2.根据openid查看该微信用户是否绑定用户
     * 3.是， 跳转登录页面
     * 4.否，跳转注册页面
     *
     * @param req
     * @param modelAndView
     * @return
     */
    @RequestMapping("/selfCenterCallback")
    public ModelAndView selfCenterCallback(HttpServletRequest req, ModelAndView modelAndView) {
        // 获取code
        String code = req.getParameter("code");
        //  根据code获取openid
        String openid = getOpenidByCode(code);
        // 根据openid查看该微信账号是否已绑定账户, 没绑定就进行绑定，绑定了就跳转至用户页面
        WxUser wxUser = wxUserService.selectByOpenId(openid);
        User user = userService.selectByWxid(wxUser.getId());
        if (null == user) {
            modelAndView.setViewName("weixin/login");
            modelAndView.addObject("wxid", wxUser.getId());
            return modelAndView;
        }
        modelAndView.addObject("user", user);
        modelAndView.setViewName("weixin/userInfo");
        return modelAndView;
    }

    /**
     * 点击发布讲座后的一些处理，通过回调拿到用户的openid
     * @param resp
     * @throws IOException
     */
    @RequestMapping("/publish")
    public void publish(HttpServletResponse resp) throws IOException {
        String redirect_uri = "";
        try {
            redirect_uri = URLEncoder.encode(domainName + "/weixin/publishCallback", "UTF-8");
        } catch (UnsupportedEncodingException e) {
            log.error("微信网页授权的回调路径encode编码错误！e : {}", e.getCause());
        }
        String url  = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
                "appid=" + appID +
                "&redirect_uri="+redirect_uri+"&response_type=code&scope=snsapi_base&state=sjzd#wechat_redirect";
        resp.sendRedirect(url);
    }

    /**
     * 点击 会议发单 回调处理：
     * 1.通过静默授权方式获取用户的openid
     * 2.根据openid查看该微信用户是否绑定用户
     * 3.是， 跳转登录页面
     * 4.否，跳转注册页面
     * @param req
     * @param modelAndView
     * @return
     */
    @RequestMapping("/publishCallback")
    public ModelAndView publishCallback(HttpServletRequest req, ModelAndView modelAndView) {
        // 获取code
        String code = req.getParameter("code");
        //  根据code获取openid
        String openid = getOpenidByCode(code);
        if (null == openid) {
            modelAndView.setViewName("error");
            return modelAndView;
        }
        //根据openid查看该微信账号是否已绑定账户, 没绑定就进行绑定，绑定了就跳转至发布订单页面
        WxUser wxUser = wxUserService.selectByOpenId(openid);
        User user = userService.selectByWxid(wxUser.getId());
        if (user.getRid() != 1) {
            modelAndView.setViewName("error");
            modelAndView.addObject("errorMsg", "你无权访问该页面");
        } else{
            modelAndView.addObject("uid", user.getId());
            modelAndView.setViewName("weixin/publish");
        }
        return modelAndView;
    }


    /**
     * 根据code获取openid
     * @param code
     * @return
     */
    public String getOpenidByCode(String code) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
                "appid=" + appID +
                "&secret=" + secret +
                "&code="+ code +"&grant_type=authorization_code";
        String json = WxUtils.httpRequest(url, "GET", null);
        JSONObject jsonObject = JSONObject.parseObject(json);
        if (null != jsonObject.getInteger("errcode")) {
            log.error("网页授权失败，errcode : {}, errmsg : {}",
                    jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
            return null;
        }
        String openid = jsonObject.getString("openid");
        return openid;
    }

}
